home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2010 April
/
PCWorld0410.iso
/
hity wydania
/
Ubuntu 9.10 PL
/
karmelkowy-koliberek-9.10-netbook-remix-PL.iso
/
casper
/
filesystem.squashfs
/
usr
/
bin
/
apport-collect
< prev
next >
Wrap
Text File
|
2009-11-03
|
6KB
|
183 lines
#!/usr/bin/python
# Download a Launchpad bug report, get its source package, check if it has
# apport hooks, and if so, run and upload them.
#
# Copyright (c) 2009 Canonical Ltd.
# Author: Martin Pitt <martin.pitt@ubuntu.com>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version. See http://www.gnu.org/copyleft/gpl.html for
# the full text of the license.
import sys, os.path, optparse, tempfile, re, email
from glob import glob
import apport
from launchpadlib.errors import HTTPError
from apport.crashdb_impl.launchpad import CrashDatabase
bug_target_re = re.compile(
r'/ubuntu/(?:(?P<suite>[^/]+)/)?\+source/(?P<source>[^/]+)$')
def upload(report, bug):
'''Upload collected information to Launchpad bug.'''
print 'Uploading additional information to Launchpad bug...'
# we want to reuse the knowledge of write_mime() with all its different input
# types and output formatting; however, we have to dissect the mime ourselves,
# since we can't just upload it as a blob
mime = tempfile.TemporaryFile()
report.write_mime(mime)
mime.flush()
mime.seek(0)
msg = email.message_from_file(mime)
msg_iter = msg.walk()
# first part is the multipart container
part = msg_iter.next()
assert part.is_multipart()
# second part should be an inline text/plain attachments with all short
# fields
part = msg_iter.next()
assert not part.is_multipart()
assert part.get_content_type() == 'text/plain'
print' short text data...'
bug.newMessage(content=part.get_payload(decode=True),
subject='apport-collect data')
# other parts are the attachments:
for part in msg_iter:
print ' attachment: %s...' % part.get_filename()
bug.addAttachment(comment='',
description=part.get_filename(),
content_type=None,
data=part.get_payload(decode=True),
filename=part.get_filename(), is_patch=False)
# change bug status from "Incomplete"
for task in bug.bug_tasks:
if task.status == 'Incomplete':
task.transitionToStatus(status='New')
def collect(report, package):
'''Collect information for given package.'''
print 'Collecting apport information for source package %s...' % package
try:
report.add_package_info(package)
except ValueError:
# this happens for source package tasks which do not have an identical
# binary package name
pass
report.add_hooks_info(None)
#
# main
#
optparser = optparse.OptionParser('%prog [options] <Launchpad bug number>')
optparser.add_option('-p', '--package',
help="Collect information for this package. If not given, it will be inferred from the bug report's source package tasks.",
type='string', dest='package')
(opts, args) = optparser.parse_args()
if len(args) != 1:
optparser.error('incorrect number of arguments; use --help for a short online help')
sys.exit(1)
try:
bug_number = int(args[0])
except ValueError:
optparser.error('invalid bug report number')
sys.exit(1)
print 'Logging into Launchpad... You have to allow "Change anything" privileges.'
crashdb = CrashDatabase(None, None, {'distro': 'ubuntu'})
print 'Downloading bug information...'
try:
bug = crashdb.launchpad.bugs[int(bug_number)]
except KeyError:
print 'The bug number %s does not exist in Launchpad.' % bug_number
sys.exit(1)
if bug.owner.name != crashdb.launchpad.me.name:
print 'You are not the reporter of bug %s.' % bug_number
while True:
val = raw_input('Is that really the bug you want to update? [y/N]')
if val.lower() in ('y', 'yes'):
break
elif val.lower() in ('n', 'no', ''):
sys.exit(1)
else:
print 'Invalid answer.'
report = apport.Report('Bug')
print 'Bug title:', bug.title
info_collected = False
if opts.package:
collect(report, opts.package)
info_collected = True
else:
# determine bug tasks and collect for those
for task in bug.bug_tasks:
match = bug_target_re.search(task.target.self_link)
if not match:
print 'Ignoring task', task.target
continue
if task.status in ('Invalid', "Won't Fix", 'Fix Released'):
print 'Ignoring task %s because it is closed' % task.target
continue
src = match.group('source')
report['SourcePackage'] = src
report['Package'] = src # no way to find this out
# we either must have the package installed or a source package hook
# available to collect sensible information
try:
apport.packaging.get_version(report['Package'])
info_collected = True
except ValueError:
if os.path.exists('/usr/share/apport/package-hooks/source_%s.py' %
report['SourcePackage']):
info_collected = True
else:
print 'Package %s not installed and no hook available, ignoring' % src
continue
collect(report, src)
report.add_os_info()
report.add_user_info()
report.add_proc_environ()
if not info_collected:
print 'No additional information collected.'
sys.exit(0)
# delete the uninteresting keys
del report['ProblemType']
del report['Date']
try:
del report['SourcePackage']
except KeyError:
pass
try:
upload(report, bug)
bug = crashdb.launchpad.bugs[int(bug_number)] # LP#336866 workaround
x = bug.tags[:] # LP#254901 workaround
x.append('apport-collected')
bug.tags = x
bug.lp_save()
except HTTPError, e:
print >> sys.stderr, 'Error connecting to Launchpad: %s\nYou have to allow "Change anything" privileges.\nYou can reset the credentials by removing the file "~/.cache/apport/launchpad.credentials."' % str(e)
sys.exit(1)